﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using System.Xml.Schema;
using System.IO;

namespace AirProperties
{
    //Air Application Properties Manager
    class PropertyManager
    {
        private static XmlDocument moAapDoc;
        private static XmlNamespaceManager moNamespaceMgr;
        private static XmlNode moRoot;
        private static Boolean mbIsInitialised;
        private static Exception moLastExpception;

        public static Exception LastException
        {
            get
            {
                return moLastExpception;
            }
        }

        public static Boolean IsInitialised
        {
            get
            {
                return mbIsInitialised;
            }
        }

        public static Boolean InitialiseProperties(string psFilePath)
        {
            Boolean lbResult = false;

            try
            {
                moAapDoc = new XmlDocument();
                moAapDoc.Load(psFilePath);

                moRoot = moAapDoc.DocumentElement;

                moNamespaceMgr = new XmlNamespaceManager(moAapDoc.NameTable);
                moNamespaceMgr.AddNamespace("air", moRoot.NamespaceURI);

                lbResult = true;
            }
            catch (Exception ex)
            {
                moLastExpception = ex;
            }
            finally
            {
                //nothing to clean up
            }

            mbIsInitialised = lbResult;
            return lbResult;
        }

        public static Boolean CommitProperties(string psFilePath)
        {
            Boolean lbResult = false;

            try
            {
                moAapDoc.Save(psFilePath);
                lbResult = true;
            }
            catch (Exception ex)
            {
                moLastExpception = ex;
            }
            finally
            {
                //nothing to clean up
            }

            mbIsInitialised = lbResult;
            return lbResult;
        }

        public static String GetProperty(string psProperty)
        {
            XmlNode loPropertyNode;

            loPropertyNode = moRoot.SelectSingleNode("air:" + psProperty.Replace("/", "/air:"), moNamespaceMgr);
            if (loPropertyNode != null)
                return loPropertyNode.InnerText;
            else
                return "";
        }

        public static void GetProperty(string psProperty, ref TextBox poTextBox)
        {
            XmlNode loPropertyNode;

            loPropertyNode = moRoot.SelectSingleNode("air:" + psProperty.Replace("/", "/air:"), moNamespaceMgr);
            if (loPropertyNode != null)
                poTextBox.Text = loPropertyNode.InnerText;
            else
                poTextBox.Text = "";
        }

        public static void GetProperty(string psProperty, ref CheckBox poCheckBox)
        {
            XmlNode loPropertyNode;

            loPropertyNode = moRoot.SelectSingleNode("air:" + psProperty.Replace("/", "/air:"), moNamespaceMgr);
            if (loPropertyNode != null)
            {
                if (loPropertyNode.InnerText.ToLower() == "true")
                    poCheckBox.Checked = true;
                else
                    poCheckBox.Checked = false;
            }
            else
                poCheckBox.CheckState = CheckState.Indeterminate;
        }

        public static void GetProperty(string psProperty, ref ComboBox poComboBox, int piDefaultIndex)
        {
            XmlNode loPropertyNode;
            Boolean lbFoundListItem = false;

            loPropertyNode = moRoot.SelectSingleNode("air:" + psProperty.Replace("/", "/air:"), moNamespaceMgr);
            if (loPropertyNode != null)
            {
                foreach (ListItem loListItem in poComboBox.Items)
                {
                    if (loListItem.Value == loPropertyNode.InnerText.ToLower())
                    {
                        poComboBox.SelectedItem = loListItem;
                        lbFoundListItem = true;
                    }
                }
                if (!lbFoundListItem)
                    poComboBox.SelectedIndex = piDefaultIndex;
            }
            else
                poComboBox.SelectedIndex = piDefaultIndex;
        }

        public static void SetProperty(string psProperty, string psValue)
        {
            XmlNode loPropertyNode;
            String lsChildName;
            int index;

            loPropertyNode = moRoot.SelectSingleNode("air:" + psProperty.Replace("/", "/air:"), moNamespaceMgr);
            if (loPropertyNode != null)
            {
                if (psValue != "")
                {
                    loPropertyNode.InnerText = psValue;
                }
                else
                {
                    //remove the node, reverting to system default
                    GetParentNode(psProperty).RemoveChild(loPropertyNode);
                }
            }
            else
            {
                //only add property if there is a value to add
                if (psValue != "")
                {
                    index = psProperty.IndexOf('/');
                    lsChildName = psProperty.Substring(index + 1, psProperty.Length - (index + 1));
                    loPropertyNode = moAapDoc.CreateNode(XmlNodeType.Element, lsChildName, moNamespaceMgr.LookupNamespace("air"));
                    if (loPropertyNode != null)
                    {
                        loPropertyNode.InnerText = psValue;
                        GetParentNode(psProperty).AppendChild(loPropertyNode);
                    }
                }
            }
        }

        public static void SetProperty(string psProperty, TextBox poTextBox)
        {
            XmlNode loPropertyNode;
            String lsChildName;
            int index;

            loPropertyNode = moRoot.SelectSingleNode("air:" + psProperty.Replace("/", "/air:"), moNamespaceMgr);
            if (loPropertyNode != null)
            {
                if (poTextBox.Text != "")
                {
                    loPropertyNode.InnerText = poTextBox.Text;
                }
                else
                {
                    //remove the node, reverting to system default
                    GetParentNode(psProperty).RemoveChild(loPropertyNode);
                }
            }
            else
            {
                //only add property if there is a value to add
                if (poTextBox.Text != "")
                {
                    index = psProperty.IndexOf('/');
                    lsChildName = psProperty.Substring(index + 1, psProperty.Length - (index + 1));
                    loPropertyNode = moAapDoc.CreateNode(XmlNodeType.Element, lsChildName, moNamespaceMgr.LookupNamespace("air"));
                    if (loPropertyNode != null)
                    {
                        loPropertyNode.InnerText = poTextBox.Text;
                        GetParentNode(psProperty).AppendChild(loPropertyNode);
                    }
                }
            }
        }

        public static void SetProperty(string psProperty, CheckBox poCheckBox)
        {
            XmlNode loPropertyNode;
            String lsChildName;
            int index;

            loPropertyNode = moRoot.SelectSingleNode("air:" + psProperty.Replace("/", "/air:"), moNamespaceMgr);
            if (loPropertyNode != null)
            {
                if (poCheckBox.CheckState != CheckState.Indeterminate)
                {
                    loPropertyNode.InnerText = poCheckBox.Checked.ToString().ToLower();
                }
                else
                {
                    //remove the node, reverting to system default
                    GetParentNode(psProperty).RemoveChild(loPropertyNode);
                }
            }
            else
            {
                //only add property if there is a value to add
                if (poCheckBox.CheckState != CheckState.Indeterminate)
                {
                    index = psProperty.IndexOf('/');
                    lsChildName = psProperty.Substring(index + 1, psProperty.Length - (index + 1));
                    loPropertyNode = moAapDoc.CreateNode(XmlNodeType.Element, lsChildName, moNamespaceMgr.LookupNamespace("air"));
                    if (loPropertyNode != null)
                    {
                        loPropertyNode.InnerText = poCheckBox.Checked.ToString().ToLower();
                        GetParentNode(psProperty).AppendChild(loPropertyNode);
                    }
                }
            }
        }

        public static void SetProperty(string psProperty, ComboBox poComboBox)
        {
            XmlNode loPropertyNode;
            ListItem loSelectedItem;
            String lsChildName;
            int index;

            loSelectedItem = (ListItem)poComboBox.SelectedItem;
            if (loSelectedItem != null)
            {
                loPropertyNode = moRoot.SelectSingleNode("air:" + psProperty.Replace("/", "/air:"), moNamespaceMgr);
                if (loPropertyNode != null)
                    loPropertyNode.InnerText = loSelectedItem.Value;
                else
                {
                    index = psProperty.IndexOf('/');
                    lsChildName = psProperty.Substring(index + 1, psProperty.Length - (index + 1));
                    loPropertyNode = moAapDoc.CreateNode(XmlNodeType.Element, lsChildName, moNamespaceMgr.LookupNamespace("air"));
                    if (loPropertyNode != null)
                    {
                        loPropertyNode.InnerText = loSelectedItem.Value;
                        GetParentNode(psProperty).AppendChild(loPropertyNode);
                    }
                }
            }
        }

        /* Simple method returns the parent node based on the supplied property name (XPATH)
         * If parent node does not exist it is created and added to the root element
         * This function will only work for a single parent/child, but that is all
         * that is required at this point as only element in AIR properties file that has more
         * than two levels is fileTypes which is not supported at the moment.
         **/
        private static XmlNode GetParentNode(string psProperty)
        {
            XmlNode loParentNode;
            String lsParentName;
            int index;

            index = psProperty.IndexOf('/');

            if (index == -1)
            {
                return moRoot;
            }
            else
            {
                lsParentName = psProperty.Substring(0, index);
                loParentNode = moRoot.SelectSingleNode("air:" + lsParentName, moNamespaceMgr);
                if (loParentNode == null)
                {
                    loParentNode = moAapDoc.CreateNode(XmlNodeType.Element, lsParentName, moNamespaceMgr.LookupNamespace("air"));
                    moRoot.AppendChild(loParentNode);
                }
                return loParentNode;
            }
        }


    }
}
